#include "TcpConnection.hpp"
#include "EventLoop.hpp"
#include "Channel.hpp"

#include <unistd.h>
#include <cstring>
#include <iostream>

TcpConnection::TcpConnection(EventLoop* loop, int sockfd, const sockaddr_in& peerAddr)
    : loop_(loop),
      sockfd_(sockfd),
      peerAddr_(peerAddr),
      channel_(new Channel(loop, sockfd)) {}

TcpConnection::~TcpConnection() {
    ::close(sockfd_);
}

int TcpConnection::fd() const {
    return sockfd_;
}

void TcpConnection::connectEstablished() {
    connected_ = true;
    // 注册读事件回调
    channel_->setReadCallback(std::bind(&TcpConnection::handleRead, shared_from_this()));
    channel_->setWriteCallback(std::bind(&TcpConnection::handleWrite, shared_from_this()));
    channel_->setCloseCallback(std::bind(&TcpConnection::handleClose, shared_from_this()));
    channel_->setErrorCallback(std::bind(&TcpConnection::handleError, shared_from_this()));

    channel_->enableReading();

    if (connectionCallback_) {
        connectionCallback_(shared_from_this());
    }
}

void TcpConnection::send(const std::string& msg) {
    //根据实际的业务去处理 msg
    if (!connected_) return;

    if (loop_) {
        // 立即写入 socket
        if (outputBuffer_.readableBytes() == 0) {
            ssize_t n = ::write(sockfd_, msg.data(), msg.size());
            if (n >= 0) {
                if (static_cast<size_t>(n) < msg.size()) {
                    outputBuffer_.append(msg.data() + n, msg.size() - n);
                    channel_->enableWriting();  // 关注写事件
                }
            } else {
                perror("write");
                outputBuffer_.append(msg);  // 写失败直接进缓冲
                channel_->enableWriting();
            }
        } else {
            outputBuffer_.append(msg);
            channel_->enableWriting();  // 之前已有数据，直接关注写事件
        }
    }
}

void TcpConnection::handleRead() {
    int savedErrno = 0;
    ssize_t n = inputBuffer_.readFd(sockfd_, &savedErrno);
    if (n > 0) {
        std::string msg = inputBuffer_.retrieveAllAsString();
        if (messageCallback_) {
            messageCallback_(shared_from_this(), msg);
        }
    } else if (n == 0) {
        handleClose();
    } else {
        perror("read");
        handleError();
    }
}

void TcpConnection::handleWrite() {
    if (channel_->isWriting()) {
        ssize_t n = ::write(sockfd_, outputBuffer_.peek(), outputBuffer_.readableBytes());
        if (n > 0) {
            outputBuffer_.retrieve(n);
            if (outputBuffer_.readableBytes() == 0) {
                channel_->disableWriting();  // 写完了，关闭写事件
            }
        } else {
            perror("write in handleWrite");
        }
    }
}

void TcpConnection::handleClose() {
    std::cout << "Connection closed, fd = " << sockfd_ << std::endl;
    channel_->disableAll();
    
    if (closeCallback_) {
        closeCallback_(shared_from_this());  // 通知 TcpServer 回收
    }
}

void TcpConnection::handleError() {
    std::cerr << "TcpConnection error on fd = " << sockfd_ << std::endl;
}

void TcpConnection::shutdown() {
    if (connected_) {
        if (!channel_->isWriting()) {
            ::shutdown(sockfd_, SHUT_WR);
        }
    }
}

